// ECE556 - Copyright 2013 University of Wisconsin-Madison.  All Rights Reserved.


#ifndef ECE556_H
#define ECE556_H

#include <stdio.h>

typedef struct  int_LL
{
        int             num;
        struct  int_LL  *next;
} int_LL;

 typedef struct point
 {
        int x ; /* x coordinate ( >=0 in the routing grid)*/
        int y ; /* y coordinate ( >=0 in the routing grid)*/
 }      point;


 typedef struct segment
 {
        int             s; 	/* start point of a segment */
        int             t;  	/* end point of a segment */
        int             dist;
        int             *edges; // fixed size of dist(s,t,rst)
 }      segment ;


  typedef struct route
  {
        int             s; 
        int             t;
        int             *immd;  // can be any non-negative integer
        int             numSegs;
        int             state;  // 0:not routed; 1:routed
        segment         *seg;   // size of #immd+1
  }     route ;

typedef struct  net
{
        int             id;
        int             numPins;
        int             *pins;  // fixed size of numPins
        route           *r;     // fixed size of numPins-1
        int_LL          *edges;
        int_LL          *nodes;
}       net;

  typedef struct routingInst
  {
   int gx ;		/* x dimension of the global routing grid */
   int gy ;		/* y dimension of the global routing grid */
   int cap ;            /* default edge capacity */
   int numNets ;	/* number of nets */
   int numEdges ; 	/* number of edges of the grid */

   net *nets ;		/* array of nets */

   int *edgeCaps; 	/* array of the actual edge capacities after considering for blockages */
   int *edgeUtils;	/* array of edge utilizations */  
   int *nodeUtils;      /* 1 for used  */

   /* dependent on how we define the weight for edges */
   float        *netWeights;    /* size of numNets */
   float        *edgeWeights;   /* size of numEdges */
   float        *hist;          /* size of numEdges */ 

  } routingInst ;

/* int readBenchmark(const char *fileName, routingInst *rst)
   Read in the benchmark file and initialize the routing instance.
   This function needs to populate all fields of the routingInst structure.
   input1: fileName: Name of the benchmark input file
   input2: pointer to the routing instance
   output: 1 if successful
*/
routingInst *readBenchmark(const char *fileName );

  
/* int solveRouting(routingInst *rst)
   This function creates a routing solution
   input: pointer to the routing instance
   output: 1 if successful, 0 otherswise (e.g. the data structures are not populated) 
*/
int solveRouting(routingInst *rst);
  
/* int writeOutput(const char *outRouteFile, routingInst *rst)
   Write the routing solution obtained from solveRouting(). 
   Refer to the project link for the required output format.

   Finally, make sure your generated output file passes the evaluation script to make sure
   it is in the correct format and the nets have been correctly routed. The script also reports
   the total wirelength and overflow of your routing solution.

   input1: name of the output file
   input2: pointer to the routing instance
   output: 1 if successful, 0 otherswise(e.g. the output file is not valid) 
  */
  int writeOutput(const char *outRouteFile, routingInst *rst);
  
  /* int release(routingInst *rst)
     Release the memory for all the allocated data structures. 
     Failure to release may cause memory problems after multiple runs of your program. 
     Need to recursively delete all memory allocations from bottom to top 
     (starting from segments then routes then individual fields within a net struct, 
     then nets, then the fields in a routing instance, and finally the routing instance)

     output: 1 if successful, 0 otherswise 
  */
 int release(routingInst *rst);


#endif // ECE556_H

